package handler;

import Client.Client;
import Factory.ListenerFactory;
import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.stream.ChunkedStream;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.HashedWheelTimer;
import promise.SuperPromise;
import sys.Console;

import java.util.*;
import java.util.concurrent.TimeUnit;

@ChannelHandler.Sharable
public class HttpHandler extends ChannelInboundHandlerAdapter {

    // 定时器
    private static final HashedWheelTimer RECONNECT_TIMER = new HashedWheelTimer();

    private static Console console = Console.getInstance();

    private static ChannelHandlerContext channelHandlerContext;

    private static ArrayDeque<String> headerIdDeque = new ArrayDeque<>();

    public static SuperPromise superPromise = new SuperPromise();

    public static Map<String, Object> results = new HashMap<>();;

    public static Object sendMessage(FullHttpRequest fullHttpRequest) throws InterruptedException {
        String contextKey = fullHttpRequest.headers().get("headerId").toString();
        headerIdDeque.addLast(contextKey);
        superPromise.createPromise(contextKey, channelHandlerContext.newPromise());
        console.log("开始发送请求");
        if (!channelHandlerContext.channel().isActive()) {
            console.error("the TCP connection is down");
            console.info("trying to reconnect it");
            Client instance = Client.getInstance();
            instance.httpConnect(ListenerFactory.getDefaultListener("重新连接成功"));
        }
        console.log("发送" + channelHandlerContext.channel().id());
        channelHandlerContext.writeAndFlush(fullHttpRequest).addListener(ListenerFactory.getDefaultListener("请求已成功发送"));
        superPromise.await(contextKey);
        return results.get(contextKey);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        console.sexy("活动:" + ctx.channel().id().toString());
        channelHandlerContext = ctx;
//        channelHandlerContext.addContext(ctx.channel().id().toString(), ctx);
//        dispatch.inStack(ctx);
//        // 启动定时器
//        RECONNECT_TIMER.newTimeout(timeout -> {
//            if (!timeout.isCancelled() ) {
//                Client.getInstance().httpConnect();
//            }
//        }, 2000, TimeUnit.MILLISECONDS);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        console.log("读取" + ctx.channel().id());
        FullHttpResponse response = (FullHttpResponse)msg;
        String key = headerIdDeque.pop();
        response.headers().add("headerid", key);
        results.put(key, response);
        superPromise.setSuccess(key);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 如果2s没有读请求，则向客户端发送心跳
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (IdleState.READER_IDLE.equals((event.state()))) {
                ctx.writeAndFlush("heartbeat").addListener(ChannelFutureListener.CLOSE_ON_FAILURE) ;
            }
        }
        super.userEventTriggered(ctx, evt);
    }
}

